﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Messaging;

using Model;
using common;

namespace BLL.MailSend
{
    public class SmtpOperation:IDisposable
    {

        public static SmtpOperation smtp=null;

        private SmtpOperation()
        {
        }

        public static SmtpOperation getInstace()
        {
            if (smtp == null)
            {
                smtp = new SmtpOperation();
            }
            return smtp;
        }

        MyEventArgs args = new MyEventArgs();   //事件参数
        public event D_CallBack PutOutInfomation;

        private Mutex mutex = new Mutex();
        private static wk_Queue myQueue = new wk_Queue();  //内存队列 用于缓冲数据
        private int threadCount = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["ThreadCount"].ToString());
        private int threadSleep = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["SLEEP"].ToString());
        //private static object obj=new object();  //局部对象锁
        //private BLLsmsmt smsmt = new BLLsmsmt(); //数据库操作类。

        /// <summary>
        /// 缓冲区长度
        /// </summary>
        private static int buflen = Int32.Parse(System.Configuration.ConfigurationManager.AppSettings["Buflen"]);

        private string messageId = string.Empty;
        private string text = string.Empty;

        public static bool readThreadFlag = false;
        public static bool writeThreadFlag = false;
        public delegate void mydelegate(object state);
        static object srcLock = new object();
        static object msgLock = new object();
        static object writeLock = new object();
        private bool isRun = false;

        public bool IsRun
        {
            get { return isRun; }
            set { isRun = value; }
        }

        #region 获取状态
        public static bool getReadThreadFlag()
        {
            return readThreadFlag;
        }

        public static bool getWriteThreadFlag()
        {
            return writeThreadFlag;
        }

        //设置发送线程退出
        public static void setReadThreadFlag()
        {
            readThreadFlag = true;
        }

        //设置接收消息队列线程退出
        public static void setThreadFlag()
        {
            writeThreadFlag = true;
        }

        //获取状态队列中的条数,
        public static string getQueueState()
        {
            string temp = string.Empty;
            temp = "" + myQueue.Count + "$" + myQueue.ReadCount + "$" + myQueue.WriteCount;
            return temp;
        }
        #endregion


        /// <summary>
        /// 开始工作
        /// </summary>
        public void Run()
        {
            if (IsRun == true)
            {
                return;
            }

            try
            {
                //读取点播队列线程.
                Thread addListThread01 = new Thread(new ParameterizedThreadStart(ReceiveWork));
                addListThread01.Name = "读取点播队列";
                addListThread01.Priority = ThreadPriority.Highest;
                addListThread01.IsBackground = true;
                addListThread01.Start("MSMQPathSend02");

                //读取群发队列线程.
                Thread addListThread = new Thread(new ParameterizedThreadStart(ReceiveWork));
                addListThread.Name = "读取群发队列";
                addListThread.IsBackground = true;
                addListThread.Start("MSMQPathSend01");

                //发送线程.
                //Thread outListThread = new Thread(new ParameterizedThreadStart(SendSmsWork));
                //outListThread.IsBackground = true;
                //outListThread.Start();

                //发送线程组。
                //System.Threading.WaitCallback waitcal = new System.Threading.WaitCallback(SendSmsWork);
                for (int i = 0; i < threadCount; i++)
                {
                    //ThreadPool.QueueUserWorkItem(waitcal);

                    ///////////////
                    //发送线程.
                    Thread outListThread = new Thread(new ParameterizedThreadStart(SendSmsWork));
                    outListThread.Name = "工作线程" + (i + 1).ToString();
                    outListThread.IsBackground = true;
                    outListThread.Start();
                }
            }
            catch (Exception ex)
            {
                Thread.Sleep(1000);
                throw ex;
            }
            args.Object_I = "邮件群发工作开始！";
            PutOutInfomation(this, args);
            isRun = true;
        }

        public void Stop()
        {
            smtp = null;
            smtp = new SmtpOperation();
        }

        #region 读取队列数据到内存队列
        /// <summary>
        ///读取队列数据到内存队列
        /// </summary>
        /// <param name="state"></param>
        public void ReceiveWork(object state)
        {
            //单线程锁.
            while (true)
            {
                if (smtp != null)
                {
                    lock (this)
                    {
                        try
                        {
                            //线程状态.
                            if (writeThreadFlag)
                            {
                                Thread.CurrentThread.Abort();
                            }
                            else
                            {
                                ReadMSMQ("" + state);   //写缓冲区
                            }
                        }
                        catch (Exception ex)
                        {
                            args.Object_I = Thread.CurrentThread.Name + ":" + state + "：线程终止";
                            this.PutOutInfomation(this, args);
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 读取send队列 写入到程序缓冲区。
        /// </summary>
        private static void ReadMSMQ(string stat)
        {
            try
            {
                using (common.MSMQHelper msmq = new common.MSMQHelper(stat))
                {
                    if (myQueue.Count < buflen)
                    {
                        System.Messaging.Message msg = new System.Messaging.Message();
                        msg = msmq.ReceiveObject();
                        if (msg == null)
                        {
                            Thread.SpinWait(10);
                        }
                        else
                        {
                            //msg.Formatter = new XmlMessageFormatter(new Type[] { typeof(MTMSGCont) });
                            msg.Formatter = new ActiveXMessageFormatter();
                            Model.Usr mtmsg = new Model.Usr();
                            //SMSMsg mtmsg =(SMSMsg) MSMQHelper.StringSerializerToObj("" + msg.Body,temSMSmsg.GetType() );
                            //StringBuilder body = new StringBuilder();
                            //StringBuilder Label = new StringBuilder();
                            //Label.Append(msg.Label);
                            //body.Append(msg.Body);

                            if (mtmsg != null)
                            {
                                lock (writeLock)
                                {
                                    myQueue.inQueue(mtmsg);  //写入程序缓存区
                                }
                            }
                            Thread.SpinWait(1);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                common.CommMethod.insertText(ex.Message);
                throw ex;
            }
        }
        #endregion

        public void SendSmsWork(object state)
        {
            using (MSMQHelper ms = new MSMQHelper("MSMQPathSmsErr"))
            {
                int n;
                while (true)
                {
                    if (readThreadFlag)
                    {
                        try
                        {
                            Thread.CurrentThread.Abort();
                        }
                        catch (Exception ex)
                        {
                            args.Object_I =Thread.CurrentThread.Name+":"+"邮件群发线程终止！";
                            PutOutInfomation(this, args);
                        }
                    }
                    else
                    {
                        n = 0;
                        //lock (this)
                        {
                            n = myQueue.Count;
                        }

                        if (n > 0)
                        {
                            mutex.WaitOne();
                            Model.Usr msg = (Usr)myQueue.outQueue();
                            mutex.ReleaseMutex();

                            if (msg != null)
                            {
                                //发送消息
                            }
                            msg = null;
                        }
                        Thread.Sleep(threadSleep);
                    }
                }
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(true);
        }

        protected virtual void Dispose(bool disposing)
        {

        }

    }
}
